const log = require('./common');

class MyPromise{

    constructor(executor){
        if(typeof executor !== 'function') throw new Error('executor is not a Function');

        this.status = 'pending';
        this.value  = undefined;
        this.onResolvedCallBacks = [];
        this.onRejectedCallBacks = [];


        try {
          executor(this.#resolve.bind(this),this.#reject.bind(this));
        } catch (error) {
          reject(error);
        }
        
        return this;
    }
  
     //#声明私有成员,防止被外部修改和访问
     #resolve(value){
        if(this.status === 'pending'){
            this.status = 'resolved';
            this.value  = value;
            this.onResolvedCallBacks.forEach(fn=>fn())
        }
     }

     #reject(reason){
        if(this.status === 'pending'){
            this.status = 'rejected';
            this.value = reason;
            this.onRejectedCallBacks.forEach(fn=>fn())
        }
     }
    
     

     then(onResolved,onRejected){
        //onResolved = typeof onResolved === 'function' ? onResolved : (value) => value;
        

        const promise2 = new MyPromise((resolve,reject) => {
   
            //该承诺状态仍未改变
            if(this.status === 'pending'){

                this.onResolvedCallBacks.push(()=>{
                    queueMicrotask(()=>{
                        try {
                            const x = onResolved(this.value); //如果有返回promise 那么x会替代promise2
                            resolvePromise(promise2,x,resolve,reject);
                        }catch(err){
                            reject(err)
                        }
                   })
                })
                this.onRejectedCallBacks.push(()=>{
                    queueMicrotask(()=>{
                        try {
                            const x = onRejected(this.value);
                            resolvePromise(promise2,x,resolve,reject);
                        }catch(err){
                            reject(err)
                        }
                   })
                })

            }else if(this.status === 'resolved'){
               queueMicrotask(()=>{
                    try {
                        const x = onResolved(this.value);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch(err){
                        reject(err)
                    }
               })
            }else{
                queueMicrotask(()=>{
                    try {
                        const x = onRejected(this.value);
                        resolvePromise(promise2,x,resolve,reject);
                    }catch(err){
                        reject(err)
                    }
               })
            }


        });

        return promise2;
    }


    static resolve = function (value) {
        return new MyPromise((resolve) => {
          resolve(value);
        });
    }

    static reject = function (value) {
        return new MyPromise((_, reject) => {
          reject(value);
        });
    }
}


function resolvePromise(promise, x, resolve, reject) {
    if (promise === x) {
      reject(new TypeError('Chaining cycle detected for promise'));
    }
  
    if (x instanceof MyPromise) {
      x.then(resolve, reject);
    } else {
      resolve(x);
    }
}
  


let promise = new MyPromise((resolve,reject)=>{
     log(1)

     setTimeout(()=>{
        resolve(2);  //class是严格模式,所以这边直接调用是指向undefined
     },3000)
})


let newpromise = promise.then(
    //Function: onResolved 传给了then
    (data)=>{
        console.log(data);
        return new MyPromise((resolve,reject)=>{
            setTimeout(()=>{
                resolve('ok!');
            },1000)
        })
    }
)

log(3);

newpromise.then(data=>{
    console.log(data)
})